﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Windows.Forms;
using System.Security;
using System.Security.Permissions;


namespace Psglass
{
    internal partial class MainForm : Form
    {
        private int _wmShellHook;

        internal MainForm()
        {
            InitializeComponent();
        }

        [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
        protected override void WndProc(ref Message m)
        {
            if (m.Msg == _wmShellHook)
            {
                switch ((int)m.WParam)
                {
                    case NativeMethods.HSHELL_WINDOWCREATED:
                        {

                            IntPtr windowHandle = m.LParam;
                            if (IsConsoleWindow(windowHandle))
                            {
                                BlurWindow(windowHandle);
                            }
                            break;
                        }
                    case NativeMethods.HSHELL_WINDOWACTIVATED:
                        {
                            NativeMethods.EmptyWorkingSet(Process.GetCurrentProcess().Handle);
                            break;
                        }

                }
            }
            base.WndProc(ref m);
        }
        private void mainForm_Load(object sender, EventArgs e)
        {

            Visible = false;
            if (!CheckSystemRequirements())
            {

                MessageBox.Show("You must have Windows Vista or higher with Desktop Composition (Aero) enabled to run this application.", "System Does Not Meet Requirements", MessageBoxButtons.OK, MessageBoxIcon.Error);
                Application.Exit();
            }


            if (IsApplicationRunningAlready())
            {
                Debug.WriteLine("App is running already");
                Application.Exit();
            }

            _wmShellHook = NativeMethods.RegisterWindowMessage("SHELLHOOK");
            NativeMethods.RegisterShellHookWindow(this.Handle);

            SetExistingConsoleWindows();
            Hide();
            
        }

        private void btnMinimize_Click(object sender, EventArgs e)
        {
            this.WindowState = FormWindowState.Minimized;
        }

        private void btnExit_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void mainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            NativeMethods.DeregisterShellHookWindow(this.Handle);
        }

        private void trayIcon_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            
            Show();
            WindowState = FormWindowState.Normal;
            
        }

        private void mainForm_Resize(object sender, EventArgs e)
        {
            if (WindowState == FormWindowState.Minimized)
                this.Hide();
            else
                this.Show();
        }

        private static bool CheckSystemRequirements()
        {
            return (Environment.OSVersion.Version.Major >= 6 && NativeMethods.DwmIsCompositionEnabled());
        }

        private static void SetExistingConsoleWindows()
        {

            Process[] proclist = Process.GetProcesses();

            foreach (Process proc in proclist)
            {
                if (proc.ProcessName.Contains("cmd") || proc.ProcessName.Contains("powershell"))
                {
                    NativeMethods.EnumWindows(CallbackFunction,proc.Id);
                }
            }
            
        }
        private static bool CallbackFunction(IntPtr hWnd, int lParam)
        {
            if (IsConsoleWindow(hWnd))
                BlurWindow(hWnd);
            return true;
        }

        private static bool IsConsoleWindow(IntPtr hWnd)
        {

            uint procID;
            NativeMethods.GetWindowThreadProcessId(hWnd, out procID);
            Process p = Process.GetProcessById((int)procID);
            string procName = p.ProcessName.ToLower();

            return (procName.Contains("powershell") || procName.Contains("cmd"));


        }
        private static void BlurWindow(IntPtr hWnd)
        {
            if (NativeMethods.DwmIsCompositionEnabled())
            {
                NativeMethods.DWM_BLURBEHIND bb;
                bb.dwFlags = (NativeMethods.DWM_BB)NativeMethods.DWM_BB_ENABLE;
                bb.fEnable = true;
                bb.fTransitionOnMaximized = true;
                bb.hRgnBlur = IntPtr.Zero;

                NativeMethods.DwmEnableBlurBehindWindow(hWnd, ref bb);
            }
            else {
                Trace.WriteLine("composition is not enabled in BlurWindow()");
            }

        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private static bool IsApplicationRunningAlready()
        {

            Process[] proclist = Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName);

            foreach (Process proc in proclist)
            {
                Debug.WriteLine(proc.Id + " " + proc.ProcessName);
                if (proc.Id != Process.GetCurrentProcess().Id && proc.ProcessName == Process.GetCurrentProcess().ProcessName)
                    return true;
            }

            return false;
        }

        private void menuItemExit_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }



    }
}
